/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package poker.greentable;

import java.util.ArrayList;
import java.util.Arrays;
import poker.cards.Card;
import poker.cards.CardsConstants;
import poker.cards.CardsSet;

/**
 * Klasa opisujaca gracza pokerowego
 * @author Norteromius
 */
public class Player
{

    private String name = "";
    private CardsSet cardsSet;
    private ArrayList<Card> cardArray = new ArrayList<Card>();
   // private ArrayList<ArrayList<Integer>> varOut = new ArrayList<ArrayList<Integer>>();
    private int numOfCardsLeft = 0;

    public Player(String name)
    {
        this.name = name;
    }

    /**
     * metoda dodajaca karty do reki gracza
     * gdy liczba kart jest odpowiednia(5)
     * nastepuje utworzenie CardsSet'a
     * @param card 
     */
    public void addCard(Card card)
    {
        cardArray.add(card);
        if (cardArray.size() == CardsConstants.KEY_SETTINGS_CARDS_IN_HAND)
        {
            cardsSet = new CardsSet(cardArray);
        }
    }

    public CardsSet getCardsSet()
    {
        return cardsSet;
    }

    public void setCardsSet(CardsSet cardsSet)
    {
        this.cardsSet = cardsSet;
    }

    public String getName()
    {
        return name;
    }

    public void setName(String name)
    {
        this.name = name;
    }
    /*
    // wariacja z powtorzeniami
    private void var(ArrayList<Integer> input, int depth, ArrayList<Integer> output)
    {
    if (depth == 0)
    {
    System.out.println(output);
    //System.out.println("LSA");
    varOut.add(output);
    } else
    {
    for (int i = 0; i < input.size(); i++)
    {
    output.add(input.get(i));
    var(input, depth - 1, output);
    output.remove(output.size() - 1);
    }
    }
    }
     */
    // kombinacja bez powtorzen

    public ArrayList<ArrayList<Integer>> comb(ArrayList<Integer> numbers)
    {
        int N = numbers.size();

        ArrayList<Integer> i;
        ArrayList<ArrayList<Integer>> combinations = new ArrayList<ArrayList<Integer>>();

        for (int len = 1; len <= N; len++)
        {
            i = new ArrayList<Integer>();
            for (int _ = 0; _ < len; _++)
            {
                i.add(len - 1 - _);
            }

            while (i.get(0) < N)
            {
                ArrayList<Integer> comb = new ArrayList<Integer>();
                for (int _ = 0; _ < len; _++)
                {
                    comb.add(numbers.get(i.get(_)));
                }
                combinations.add(comb);

                for (int _ = 0; _ < len; _++)
                {
                    i.set(_, i.get(_) + 1);
                    if (i.get(_) < N)
                    {
                        break;
                    }
                    if (_ < len - 1)
                    {
                        i.set(_, i.get(_ + 1) + 2);
                    }
                }
            }

            i = null;
        }

        return combinations;

    }

    
    // temp - indeksy kart do zamiany
    public String changeCards(ArrayList<Integer> temp)
    {

        String out = "";
        double prawd;
        double suma_p;
        boolean no;
        int currentPower = this.getCardsSet().getValue();

        ArrayList<ArrayList<Integer>> cardsOut = comb(temp);

        for (int i = 0; i < cardsOut.size(); i++)       // kolejne wektory z numerami kart do wymiany
        {
            suma_p = 0;
            out += (" Zamieniono karty : ");
            for (int w = 0; w < cardsOut.get(i).size(); w++)
            {
                int num = cardsOut.get(i).get(w);
                out += cardsSet.getCardAt(num) + " ";
                //out += ((cardsOut.get(i).get(w) + 1) + " ");
            }
            out += "\n";

            int num = cardsOut.get(i).size();    // tyle kart do wymiany
            System.out.println(num + " kart do wymiany: " + cardsOut.get(i));

            Card[] newCard = new Card[num];
            int[] a = new int[num];


            // gdy trzy do wymiany
            if (num == 3)
            {
                for (a[0] = 0; a[0] < 52; a[0]++)
                {
                    //System.out.println("postęp : " + (100 * a[0] / 52) + "%");
                    for (a[1] = a[0] + 1; a[1] < 52; a[1]++)
                    {
                        for (a[2] = a[1] + 1; a[2] < 52; a[2]++)
                        {
                            // create new set
                            ArrayList<Card> tempx = new ArrayList<Card>(cardsSet.getCardsSet());

                            no = false;

                            for (int g = 0; g < num; g++)
                            {
                                newCard[g] = new Card(a[g]);

                                if (tempx.contains(newCard[g]))
                                {
                                    no = true;
                                    break;
                                }
                            }
                            if (!no)
                            {
                                for (int g = 0; g < num; g++)
                                {
                                    tempx.set(cardsOut.get(i).get(g), newCard[g]);
                                }

                                // wylosowano nowy zestaw kart

                                CardsSet tmpCards = new CardsSet(tempx);

                                // okresl sile
                                if (tmpCards.getValue() > currentPower)
                                {
                                prawd = 1.0;
                                for (int c = 0; c < num; c++)
                                {
                                    prawd *= 1. / (numOfCardsLeft-c);
                                }
                                suma_p += prawd;
                                }
                            }
                        }
                    }
                }
            } // gdy dwie do wymiany
            else if (num == 2)
            {
                for (a[0] = 0; a[0] < 52; a[0]++)
                {
                    for (a[1] = a[0] + 1; a[1] < 52; a[1]++)
                    {
                        // create new set
                        ArrayList<Card> tempx = new ArrayList<Card>(cardsSet.getCardsSet());

                        no = false;

                        for (int g = 0; g < num; g++)
                        {
                            newCard[g] = new Card(a[g]);

                            if (tempx.contains(newCard[g]))
                            {
                                no = true;
                                break;
                            }
                        }
                        if (!no)
                        {
                            for (int g = 0; g < num; g++)
                            {
                                tempx.set(cardsOut.get(i).get(g), newCard[g]);
                            }

                            // wylosowano nowy zestaw kart

                            CardsSet tmpCards = new CardsSet(tempx);

                            // okresl sile
                            if (tmpCards.getValue() > currentPower)
                            {
                                prawd = 1.0;
                                for (int c = 0; c < num; c++)
                                {
                                    prawd *= 1. / (numOfCardsLeft-c);
                                }
                                suma_p += prawd;
                            }
                        }

                    }
                }
            } // gdy jedna do wymiany
            else if (num == 1)
            {

                for (a[0] = 0; a[0] < 52; a[0]++)
                {
                    // create new set
                    ArrayList<Card> tempx = new ArrayList<Card>(cardsSet.getCardsSet());

                    no = false;

                    for (int g = 0; g < num; g++)
                    {
                        newCard[g] = new Card(a[g]);

                        if (tempx.contains(newCard[g]))
                        {
                            no = true;
                            break;
                        }
                    }
                    if (!no)
                    {
                        for (int g = 0; g < num; g++)
                        {
                            tempx.set(cardsOut.get(i).get(g), newCard[g]);
                        }

                        // wylosowano nowy zestaw kart

                        CardsSet tmpCards = new CardsSet(tempx);

                        // okresl sile
                        if (tmpCards.getValue() > currentPower)
                        {
                                prawd = 1.0;
                                for (int c = 0; c < num; c++)
                                {
                                    prawd *= 1. / (numOfCardsLeft-c);
                                }
                                suma_p += prawd;
                        }
                    }

                }
            }

            out += ("  Prawdopodobienstwo powodzenia: " + suma_p + "\n");
            //out += ("  Suma punktów do zdobycia: " + suma_p + "\n");
        }

        return out;
    }

    // ktora karte wymienic ?
    // tylko gdy mamy pare, dwie pary, trojke, karete, lub nic
    public String whichCardChange(int num)
    {
        
        numOfCardsLeft = 52-5*num;

        String out = "";

        // sprawdz karty do wymiany

        //  ********************************************************************
        //  *****************         gdy mamy karete        *******************
        //  ********************************************************************


        if (this.getCardsSet().getKind().equals(CardsConstants.KEY_SET_FOUR_OF_KIND))
        {
            ArrayList<Integer> temp = new ArrayList<Integer>(Arrays.asList(0, 1, 2, 3, 4));

            temp.removeAll(this.getCardsSet().listOfSecond);

            out += ("Karta niepotrzebna : " + cardsSet.getCardAt(temp.get(0)) + "\n");

            out += changeCards(temp);

        } /*  ********************************************************************
         ***************         gdy mamy dwie dwojki        ****************
         ******************************************************************* */ else if (this.getCardsSet().getKind().equals(CardsConstants.KEY_SET_TWO_PAIRS))
        {
            ArrayList<Integer> temp = new ArrayList<Integer>(Arrays.asList(0, 1, 2, 3, 4));

            temp.removeAll(this.getCardsSet().listOfSecond);
            temp.removeAll(this.getCardsSet().listOfFirst);

            out += ("Karta niepotrzebna : " + cardsSet.getCardAt(temp.get(0)) + "\n");

            out += changeCards(temp);
        } /*  ********************************************************************
         *****************         gdy mamy trojke        *******************
         ******************************************************************* */ else if (this.getCardsSet().getKind().equals(CardsConstants.KEY_SET_THREE_OF_KIND))
        {
            ArrayList<Integer> temp = new ArrayList<Integer>(Arrays.asList(0, 1, 2, 3, 4));

            temp.removeAll(this.getCardsSet().listOfSecond);

            out += ("Karty niepotrzebne : " + cardsSet.getCardAt(temp.get(0)) + " " + cardsSet.getCardAt(temp.get(1)) + "\n");

            out += changeCards(temp);

        } //  ********************************************************************
        //  *****************         gdy mamy dwojke        *******************
        //  ********************************************************************
        else if (this.getCardsSet().getKind().equals(CardsConstants.KEY_SET_PAIR))
        {
            ArrayList<Integer> temp = new ArrayList<Integer>(Arrays.asList(0, 1, 2, 3, 4));

            temp.removeAll(this.getCardsSet().listOfSecond);

            out += ("Karty niepotrzebne : " + cardsSet.getCardAt(temp.get(0)) + " "
                    + cardsSet.getCardAt(temp.get(1)) + " " + cardsSet.getCardAt(temp.get(2)) + "\n");

            out += changeCards(temp);
        } //  ********************************************************************
        //  *****************         gdy nic nie mamy        ******************
        //  ********************************************************************
        else if (this.getCardsSet().getKind().equals(CardsConstants.KEY_SET_NOTHING))
        {
            ArrayList<Integer> temp = new ArrayList<Integer>(Arrays.asList(0, 1, 2, 3, 4));

            temp.removeAll(this.getCardsSet().listOfSecond);

            out += ("Nic nie mamy\n");

            out += changeCards(temp);
        }
        return out;
    }
}
